package com.gxa.jjty.cjr.controller;


import com.gxa.jjty.core.common.JsonResult;
import com.gxa.jjty.core.exception.BusinessException;
import lombok.extern.log4j.Log4j2;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Map;
import java.util.Set;

/**
 * 本质上,就是一个aop的通知,专门用于加强异常出现的时候的抛出通知
 * @author bill
 * @date 2021/10/21 15:20
 */
@RestController
@ControllerAdvice
@Log4j2
public class ExceptionController {

//    private final JsonResult jsonResult=new JsonResult();

    /**
     *  业务异常
     */
    @ExceptionHandler(BusinessException.class)
    public Map<String,Object> businessHandler(BusinessException e) {
        //TODO 可以在TODO窗口查看,用来快速查找没写的的模块,用来做标记
        final JsonResult jsonResult = new JsonResult();
        jsonResult.setCode( e.getExceptionCode().getCode());
        jsonResult.setMsg(e.getMessage());
        return jsonResult.getDataMap();
    }

    /**
     *  系统异常
     */
    @ExceptionHandler(Exception.class)
    public Map<String,Object> exceptionHandler(Exception e){

        StringBuilder stringBuilder=new StringBuilder("-----------------begin-----------------------");
        
        // 再遍历栈中的异常轨迹: 采用遍历方式
        StackTraceElement[] stackTrace = e.getStackTrace();
        for (StackTraceElement stackTraceElement : stackTrace) {
            stringBuilder.append(stackTraceElement);
        }

        //分割线方便阅读
        stringBuilder.append("-------------------end---------------------");
        log.error(stringBuilder);
        //给前端返回系统繁忙
        final JsonResult jsonResult = new JsonResult();
        jsonResult.setCode("500");
        jsonResult.setMsg("系统繁忙,请稍后再试!");
        return jsonResult.getDataMap();
    }

    @ExceptionHandler({BindException.class, MethodArgumentNotValidException.class})
    public Map<String,Object> handleBindException(Errors errors){
        JsonResult jsonResult = new JsonResult();
        jsonResult.setCode("0");
        StringBuilder stringBuilder = new StringBuilder();
        errors.getAllErrors().forEach(error->{
            stringBuilder.append(error.getDefaultMessage()+",");
        });
        stringBuilder.deleteCharAt(stringBuilder.length()-1);
        jsonResult.setMsg(stringBuilder.toString());
        return jsonResult.getDataMap();
    }

    @ExceptionHandler(ConstraintViolationException.class)
    public Map handleConstraintViolationException(ConstraintViolationException exception) {
        StringBuilder errorInfo = new StringBuilder();
        String errorMessage ;

        Set<ConstraintViolation<?>> violations = exception.getConstraintViolations();
        for (ConstraintViolation<?> item : violations) {
            errorInfo.append(item.getMessage()).append(",");
        }
        // 处理掉最后一个多余的","
        errorMessage = errorInfo.toString().substring(0, errorInfo.toString().length()-1);
        final JsonResult jsonResult = new JsonResult();
        jsonResult.setCode("0");
        jsonResult.setMsg(errorMessage);
        return jsonResult.getDataMap();
    }

}
